package x.ovo.wechat.bot.common.contact;

import x.ovo.wechat.bot.common.Manager;
import x.ovo.wechat.bot.common.entity.Contact;
import x.ovo.wechat.bot.common.entity.Member;
import x.ovo.wechat.bot.common.exception.RetrievalStratrgyException;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * 联系人管理接口，扩展自Manager接口。
 * 提供了对联系人各种维度的检索、移除、同步以及缓存管理的方法。
 * @author ovo, created by 2024/05/03
 */
public interface ContactManager extends Manager {

    Map<RetrievalType, RetrievalStratrgy> STRATRGY_MAP = new HashMap<>(4, 1);

    /**
     * 根据检索类型和键值获取联系人。
     *
     * @param type 检索类型，决定了如何使用键值来搜索联系人。
     * @param key 根据检索类型来定位特定联系人的键值。
     * @return 返回匹配的联系人对象，如果没有找到则返回null。
     */
    Contact getContact(RetrievalType type, String key);

    /**
     * 根据用户名获取联系人。
     *
     * @param userName 联系人的用户名。
     * @return 返回匹配的联系人对象，如果没有找到则返回null。
     */
    Contact getContactByUserName(String userName);

    /**
     * 根据昵称获取联系人。
     *
     * @param nickName 联系人的昵称。
     * @return 返回匹配的联系人对象，如果没有找到则返回null。
     */
    Contact getContactByNickName(String nickName);

    /**
     * 根据备注名获取联系人。
     *
     * @param remarkName 联系人的备注名。
     * @return 返回匹配的联系人对象，如果没有找到则返回null。
     */
    Contact getContactByRemarkName(String remarkName);

    /**
     * 移除指定键值的联系人。
     *
     * @param key 要移除的联系人的键值。
     */
    void removeContact(String key);

    /**
     * 同步最近联系人列表。
     *
     * @param contacts 需要同步的联系人集合。
     */
    void syncRecentContact(Collection<Contact> contacts);

    /**
     * 刷新联系人缓存。
     */
    void flushContact();

    /**
     * 刷新群组缓存。
     */
    void flushGroup();

    /**
     * 从指定的群组中获取指定成员的信息。
     *
     * @param groupUserName 群组的名称，指定要从中获取成员的群组。
     * @param memberUserName 成员的用户名，指定要获取信息的成员。
     * @return {@link Contact} 返回一个Contact对象，包含指定成员的详细信息。
     */
    Member getGroupMember(String groupUserName, String memberUserName);

    /**
     * 按昵称获取组成员
     *
     * @param groupNickName 组昵称
     * @param name          名字
     * @return {@link Member }
     */
    Member getGroupMemberByNickName(String groupNickName, String name);

    /**
     * 同时刷新联系人和群组缓存。
     * 该方法为默认方法，提供了刷新联系人和群组缓存的便利途径。
     */
    default void flush() {
        this.flushContact(); // 刷新联系人缓存
        this.flushGroup();   // 刷新群组缓存
    }

    /**
     * 获取 Stratrgy
     *
     * @param type 类型
     * @return {@link RetrievalStratrgy }
     */
    default RetrievalStratrgy getStratrgy(RetrievalType type) {
        return Optional.ofNullable(STRATRGY_MAP.get(type)).orElseThrow(() -> new RetrievalStratrgyException(type));
    }
}

